﻿using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using MPMovieCatalog.Configuration;
using MPMovieCatalog.Configuration.Sections;
using MPMovieCatalog.Domain;
using MPMovieCatalog.Service;
using MPMovieCatalog.Util;

namespace MPMovieCatalog.Forms
{
    public partial class ApplicationForm : Form
    {
        public ApplicationForm()
        {
            InitializeComponent();

            ResourceUtils.Refresh();
            foreach (LanguageFile languageFile in ResourceUtils.GetLanguages())
            {
                ToolStripMenuItem menuItem = new ToolStripMenuItem(languageFile.Language);
                menuItem.Click += new EventHandler(ChangeLanguage);
                languageMenuItem.DropDownItems.Add(menuItem);

                if (languageFile.Language == ResourceUtils.GetCurrentLanguage())
                {
                    menuItem.Checked = true;
                }
            }

            UpdateUI();
        }

        private void ApplicationForm_Load(object sender, EventArgs e)
        {
            LoadSettings();
            RefreshList();
        }

        private void exitMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void movieGrid_SelectionChanged(object sender, EventArgs e)
        {
            ShowMovieInfo();
        }

        private void RefreshList()
        {
            if (MovieServiceFactory.IsInitialized)
            {
                BindingList<MovieShortInfo> bindingList = new BindingList<MovieShortInfo>();
                foreach (MovieShortInfo movie in MovieServiceFactory.getMovieService().FindAllMoviesShortInfo())
                {
                    bindingList.Add(movie);
                }
                bindingSource.DataSource = bindingList;
                movieCountLabel.Text = string.Format(ResourceUtils.GetString("main", 6), bindingSource.Count.ToString());
            }
        }


        private void LoadSettings()
        {
            ConfigurationWrapper configurationWrapper = new ConfigurationWrapper();
            ConnectionSection connectionSection = configurationWrapper.ConnectionSection;
            try
            {
                MovieServiceFactory.Initialize(connectionSection.Host, connectionSection.Port);
            }
            catch
            {
                MessageBox.Show(this, ResourceUtils.GetString("main", 7), ResourceUtils.GetString("common", 0), MessageBoxButtons.OK, MessageBoxIcon.Error);
                bindingSource.DataSource = null;
            }
        }

        private void movieGrid_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                EditMovie(sender, e);
            }
        }

        public void AddMovie(object sender, EventArgs e)
        {
            using (EditForm editForm = new EditForm())
            {
                IMovieService movieService = MovieServiceFactory.getMovieService();
                editForm.AvailableGenres = movieService.FindAvailableGenres(0);
                editForm.AvailableActors = movieService.FindAvailableActors(0);
                editForm.Data = new MovieInfo();
                if (editForm.ShowDialog(this) == DialogResult.OK)
                {
                    MovieInfo movieInfo = editForm.Data;
                    movieInfo.Picture = File.Exists(movieInfo.PictureFileName) ? Convert.ToBase64String(File.ReadAllBytes(movieInfo.PictureFileName)) : null;
                    movieService.InsertMovieInfo(movieInfo);

                    RefreshList();
                }
            }
        }

        public void EditMovie(object sender, EventArgs e)
        {
            MovieShortInfo movieShortInfo = (MovieShortInfo)bindingSource.Current;

            IMovieService movieService = MovieServiceFactory.getMovieService();
            MovieInfo movieInfo = movieService.FindMovieInfoById(movieShortInfo.Id);
            if (movieInfo != null && movieInfo.Picture != null && movieInfo.Picture != string.Empty)
            {
                movieInfo.PictureFileName = Utils.GetTempFileName();
                File.WriteAllBytes(movieInfo.PictureFileName, Convert.FromBase64String(movieInfo.Picture));
            }

            using (EditForm editForm = new EditForm())
            {
                editForm.AvailableGenres = movieService.FindAvailableGenres(movieShortInfo.Id);
                editForm.AvailableActors = movieService.FindAvailableActors(movieShortInfo.Id);
                editForm.Data = movieInfo;
                if (editForm.ShowDialog(this) == DialogResult.OK)
                {
                    MovieInfo updatedMovieInfo = editForm.Data;
                    bool updatePicture = movieInfo.PictureFileName != updatedMovieInfo.PictureFileName || movieInfo.Name != updatedMovieInfo.Name;
                    updatedMovieInfo.Picture = updatePicture && File.Exists(updatedMovieInfo.PictureFileName) ? Convert.ToBase64String(File.ReadAllBytes(updatedMovieInfo.PictureFileName)) : null;
                    movieService.UpdateMovieInfo(updatedMovieInfo, updatePicture);

                    ((MovieShortInfo)bindingSource.Current).Name = updatedMovieInfo.Name;
                    ShowMovieInfo();
                }
            }
        }

        public void DeleteMovie(object sender, EventArgs e)
        {
            MovieShortInfo movieShortInfo = (MovieShortInfo)bindingSource.Current;
            if (MessageBox.Show(string.Format(ResourceUtils.GetString("main", 8), movieShortInfo.Name), ResourceUtils.GetString("common", 1), MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                MovieServiceFactory.getMovieService().DeleteMovieInfo(movieShortInfo);
                bindingSource.RemoveCurrent();
            }
        }

        public void ChangeSettings(object sender, EventArgs e)
        {
            using (ConfigurationForm settingForm = new ConfigurationForm())
            {
                if (settingForm.ShowDialog() == DialogResult.OK)
                {
                    settingForm.SaveSettings();
                    LoadSettings();
                    RefreshList();
                }
            }
        }

        public void ShowMovieInfo()
        {
            if (bindingSource.Current == null) return;

            MovieShortInfo movieShortInfo = (MovieShortInfo)bindingSource.Current;
            MovieInfo movieInfo = MovieServiceFactory.getMovieService().FindMovieInfoById(movieShortInfo.Id);

            browser.DocumentText = Utils.TransformMovie(movieInfo);
        }

        private void EditMovie(object sender, DataGridViewCellEventArgs e)
        {
            EditMovie(sender, (EventArgs)e);
        }

        private void ApplicationForm_Shown(object sender, EventArgs e)
        {
            ShowMovieInfo();
        }

        private void RefreshList(object sender, EventArgs e)
        {
            RefreshList();
        }

        private void ApplicationForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            MPMovieCatalog.Util.Utils.DeleteTempFiles();
        }

        private void UpdateUI()
        {
            fileMenuItem.Text = ResourceUtils.GetString("main", 0);
            exitMenuItem.Text = ResourceUtils.GetString("main", 1);
            toolsMenuItem.Text = ResourceUtils.GetString("main", 2); ;
            languageMenuItem.Text = ResourceUtils.GetString("main", 3); ;
            settingsMenuItem.Text = ResourceUtils.GetString("main", 4); ;
            titleColumn.HeaderText = ResourceUtils.GetString("main", 5); ;
            movieCountLabel.Text = string.Format(ResourceUtils.GetString("main", 6), bindingSource.Count.ToString());

            addMenuItem.Text = ResourceUtils.GetString("main", 9);
            editMenuItem.Text = ResourceUtils.GetString("main", 10);
            deleteMenuItem.Text = ResourceUtils.GetString("main", 11);
            refreshMenuItem.Text = ResourceUtils.GetString("main", 12);
        }

        private void ChangeLanguage(object sender, EventArgs e)
        {
            ToolStripMenuItem currentLanguageMenuItem = sender as ToolStripMenuItem;

            ConfigurationWrapper wrapper = new ConfigurationWrapper();
            wrapper.GUISection.Language = currentLanguageMenuItem.Text;
            wrapper.SaveConfiguration();

            foreach (ToolStripMenuItem menuItem in languageMenuItem.DropDownItems)
            {
                menuItem.Checked = false;
            }
            currentLanguageMenuItem.Checked = true;

            ResourceUtils.Refresh();
            UpdateUI();
            ShowMovieInfo();
        }
    }
}